package com.example.controller;

import com.example.domain.BorrowRecord;
import com.example.domain.User;
import com.example.dto.BorrowQueryDTO;
import com.example.dto.BorrowRequestDTO;
import com.example.dto.BorrowResponseDTO;
import com.example.dto.ReturnRequestDTO;
import com.example.dto.BorrowBookDTO;
import com.example.vo.BorrowRecordVO;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.example.service.BorrowService;
import com.example.service.OperationLogService;
import com.example.service.UserService;
import com.example.util.Result;
import io.swagger.v3.oas.annotations.Operation;
import jakarta.servlet.http.HttpServletRequest;
import jakarta.validation.Valid;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.access.prepost.PreAuthorize;
import org.springframework.security.core.Authentication;
import org.springframework.security.core.context.SecurityContextHolder;
import org.springframework.web.bind.annotation.*;

import java.util.List;

/**
 * 借阅管理控制器
 * 
 * @author HP
 * @description 借阅相关接口
 * @createDate 2025-08-27
 */
@Slf4j
@RestController
@RequestMapping("/api/borrow")
public class BorrowController {

    @Autowired
    private BorrowService borrowService;
    
    @Autowired
    private OperationLogService operationLogService;
    
    @Autowired
    private UserService userService;

    /**
     * 获取当前登录用户ID
     * @return 用户ID
     */
    private Long getCurrentUserId() {
        Authentication auth = SecurityContextHolder.getContext().getAuthentication();
        if (auth != null && auth.isAuthenticated() && !"anonymousUser".equals(auth.getName())) {
            String username = auth.getName();
            try {
                // 通过用户名查询用户ID
                User user = userService.getUserByUsername(username);
                return user != null ? user.getId() : null;
            } catch (Exception e) {
                // 如果查询失败，返回null
                return null;
            }
        }
        return null;
    }

    /**
     * 借阅图书
     * @param borrowBookDTO 借阅请求
     * @return 操作结果
     */
    @PostMapping
    @PreAuthorize("hasRole('ROLE_USER')")
    public Result borrowBook(@RequestBody @Valid BorrowBookDTO borrowBookDTO, HttpServletRequest request) {
        // 获取当前登录用户信息
        Long currentUserId = getCurrentUserId();
        if (currentUserId == null) {
            return Result.error("用户未登录");
        }
        return borrowService.borrowBook(borrowBookDTO);
    }

    /**
     * 归还图书
     * @param returnRequestDTO 归还请求
     * @return 操作结果
     */
    @PostMapping("/return")
    @PreAuthorize("hasAnyRole('ROLE_ADMIN','ROLE_USER')")
    public Result returnBook(@RequestBody @Valid ReturnRequestDTO returnRequestDTO) {
        return borrowService.returnBook(returnRequestDTO);
    }

    /**
     * 获取用户借阅记录
     * @param userId 用户ID
     * @return 借阅记录列表
     */
    @GetMapping("/user/{userId}")
    @PreAuthorize("hasAnyRole('ROLE_ADMIN','ROLE_USER')")
    public Result getUserBorrowRecords(@PathVariable Long userId) {
        try {
            if (userId == null || userId <= 0) {
                return Result.error("用户ID无效");
            }
            
            // 普通用户只能查询自己的借阅记录
            Long currentUserId = getCurrentUserId();
            Authentication auth = SecurityContextHolder.getContext().getAuthentication();
            boolean isAdmin = auth.getAuthorities().stream()
                .anyMatch(a -> a.getAuthority().equals("ROLE_ADMIN") || a.getAuthority().equals("ROLE_SUPER_ADMIN"));
            
            if (!isAdmin && !userId.equals(currentUserId)) {
                return Result.error("无权限查询其他用户的借阅记录");
            }
            
            List<BorrowRecordVO> records = borrowService.getBorrowRecordsWithBookInfoByUserId(userId);
            return Result.success(records);
        } catch (Exception e) {
            return Result.error("查询借阅记录失败：" + e.getMessage());
        }
    }

    /**
     * 获取图书借阅记录
     * @param bookId 图书ID
     * @return 借阅记录列表
     */
    @GetMapping("/book/{bookId}")
    @PreAuthorize("hasAnyRole('ROLE_ADMIN','ROLE_SUPER_ADMIN')")
    public Result getBookBorrowRecords(@PathVariable Long bookId) {
        try {
            if (bookId == null || bookId <= 0) {
                return Result.error("图书ID无效");
            }
            List<BorrowRecord> records = borrowService.getBorrowRecordsByBookId(bookId);
            return Result.success(records);
        } catch (Exception e) {
            return Result.error("查询借阅记录失败：" + e.getMessage());
        }
    }

    /**
     * 获取逾期借阅记录
     * @return 逾期借阅记录列表
     */
    @GetMapping("/overdue")
    @PreAuthorize("hasAnyRole('ROLE_ADMIN','ROLE_SUPER_ADMIN')")
    public Result getOverdueBorrowRecords() {
        try {
            List<BorrowRecord> records = borrowService.getOverdueBorrowRecords();
            
            // 获取当前登录用户ID并记录管理员查询逾期记录的操作
            Long operatorId = getCurrentUserId();
            if (operatorId != null) {
                operationLogService.recordLog(
                    operatorId,
                    0L, // 没有特定实体ID
                    2, // 2表示借阅记录实体类型
                    "查询逾期借阅记录，共" + records.size() + "条"
                );
            }
            
            return Result.success(records);
        } catch (Exception e) {
            return Result.error("查询逾期记录失败：" + e.getMessage());
        }
    }

    /**
     * 续借图书
     * @param borrowId 借阅记录ID
     * @return 操作结果
     */
    @PostMapping("/renew/{borrowId}")
    @PreAuthorize("hasAnyRole('ROLE_ADMIN','ROLE_USER')")
    public Result renewBook(@PathVariable Long borrowId, HttpServletRequest request) {
        try {
            if (borrowId == null || borrowId <= 0) {
                return Result.error("借阅记录ID无效");
            }
            
            Long currentUserId = getCurrentUserId();
            if (currentUserId == null) {
                return Result.error("用户未登录");
            }
            
            Authentication authentication = SecurityContextHolder.getContext().getAuthentication();
            String operatorName = authentication != null ? authentication.getName() : "unknown";
            String ip = request.getRemoteAddr();
            
            boolean success = borrowService.renewBook(borrowId, 14, currentUserId, operatorName, ip);
            
            if (success) {
                // 记录操作日志
                operationLogService.recordLog(
                    currentUserId,
                    borrowId,
                    2, // 2表示借阅记录实体类型
                    "续借图书：借阅记录ID=" + borrowId
                );
                return Result.success("续借成功");
            } else {
                return Result.error("续借失败");
            }
        } catch (Exception e) {
            return Result.error("续借失败：" + e.getMessage());
        }
    }

    /**
     * 获取用户当前借阅数量
     * @param userId 用户ID
     * @return 借阅数量
     */
    @GetMapping("/count/{userId}")
    @PreAuthorize("hasAnyRole('ROLE_ADMIN','ROLE_USER')")
    public Result getUserBorrowCount(@PathVariable Long userId) {
        try {
            if (userId == null || userId <= 0) {
                return Result.error("用户ID无效");
            }
            
            // 普通用户只能查询自己的借阅数量
            Long currentUserId = getCurrentUserId();
            Authentication auth = SecurityContextHolder.getContext().getAuthentication();
            boolean isAdmin = auth.getAuthorities().stream()
                .anyMatch(a -> a.getAuthority().equals("ROLE_ADMIN") || a.getAuthority().equals("ROLE_SUPER_ADMIN"));
            
            if (!isAdmin && !userId.equals(currentUserId)) {
                return Result.error("无权限查询其他用户的借阅数量");
            }
            
            int count = borrowService.getUserCurrentBorrowCount(userId);
            return Result.success(count);
        } catch (Exception e) {
            return Result.error("查询借阅数量失败：" + e.getMessage());
        }
    }

    /**
     * 检查用户借阅资格
     * @param userId 用户ID
     * @param bookId 图书ID
     * @return 检查结果
     */
    @GetMapping("/check-eligibility")
    @PreAuthorize("hasAnyRole('ROLE_ADMIN','ROLE_USER')")
    public Result checkBorrowEligibility(@RequestParam Long userId, @RequestParam Long bookId) {
        try {
            if (userId == null || userId <= 0) {
                return Result.error("用户ID无效");
            }
            if (bookId == null || bookId <= 0) {
                return Result.error("图书ID无效");
            }
            
            String result = borrowService.checkBorrowEligibility(userId, bookId);
            if ("OK".equals(result)) {
                return Result.success("可以借阅");
            } else {
                return Result.error(result);
            }
        } catch (Exception e) {
            return Result.error("检查借阅资格失败：" + e.getMessage());
        }
    }
    
    /**
     * 获取图书的可用副本ID
     * @param bookId 图书ID
     * @return 可用副本ID
     */
    @GetMapping("/available-copy/{bookId}")
    @PreAuthorize("hasRole('USER') or hasRole('ADMIN')")
    public Result getAvailableBookCopyId(@PathVariable Long bookId) {
        try {
            Long availableCopyId = borrowService.getAvailableBookCopyId(bookId);
            if (availableCopyId != null) {
                return Result.success(availableCopyId);
            } else {
                return Result.error("该图书暂无可用副本");
            }
        } catch (Exception e) {
            return Result.error("查询失败：" + e.getMessage());
        }
    }
    
    @GetMapping("/copy-status/{bookCopyId}")
    @Operation(summary = "获取图书副本借阅状态")
    public Result getBookCopyBorrowStatus(@PathVariable Long bookCopyId) {
        try {
            // 查询该副本的借阅记录
            QueryWrapper<BorrowRecord> queryWrapper = new QueryWrapper<>();
            queryWrapper.eq("book_copy_id", bookCopyId)
                       .eq("borrow_status", 0); // 0表示借阅中
            
            BorrowRecord borrowRecord = borrowService.getOne(queryWrapper);
            
            if (borrowRecord != null) {
                return Result.success("已借出");
            } else {
                return Result.success("可借阅");
            }
        } catch (Exception e) {
            log.error("获取图书副本状态失败", e);
            return Result.error("获取状态失败：" + e.getMessage());
        }
    }
}
